<?php

namespace App\Http\Admin\Services;

use App\Api\Exceptions\BusinessException;
use App\Models\Admin\Permission;
use Illuminate\Database\Eloquent\Builder as BuilderAlias;
use Illuminate\Database\Eloquent\Model;

class AdminPermissionService extends BaseService
{

    /**
     * 获取目录填充参数
     * @param $datas
     * @return array
     */
    public function getCatalogueParams($datas): array
    {
        return $this->array_intersect_ktv($datas, ['name', 'title', 'type', 'parent_id', 'is_show', 'icon', 'order_num']);
    }

    /**
     * 获取菜单填充参数
     * @param $datas
     * @return array
     */
    public function getMenuParams($datas): array
    {
        return $this->array_intersect_ktv($datas, ['name', 'title', 'type', 'parent_id', 'is_show', 'icon', 'order_num', 'keep_alive', 'view_path', 'router']);
    }

    /**
     * 获取权限填充参数
     * @param $datas
     * @return array
     */
    public function getButtonParams($datas): array
    {
        return $this->array_intersect_ktv($datas, ['name', 'title', 'type', 'parent_id', 'order_num']);
    }


    /**
     * 父类校验
     * @param $datas
     * @return void
     */
    public function parentCheck($datas)
    {
        if (isset($datas['parent_id']) && !empty($datas['parent_id']))
            Permission::findOrFail($datas['parent_id']);
    }


    /**
     * 树形结构
     * @param array $params
     * @param string $guard_name
     * @return array
     */
    public function listPermissionTree(array $params, string $guard_name = 'sanctum'): array
    {
        $data = Permission::where('guard_name', '=', $guard_name)->orderByDesc('order_num')->get()->toArray();
        $datas['total'] = Permission::where(['guard_name' => $guard_name, 'parent_id' => 0])->count();
        $datas['rows'] = isset($params['offset']) && isset($params['limit']) ? array_slice($this->getTree($data), $params['offset'], $params['limit']) : $this->getTree($data);
        return $datas;
    }

    /**
     * 添加权限/菜单/目录
     * @param $datas
     * @return Model|BuilderAlias
     */
    public function addPermission($datas): Model|BuilderAlias
    {
        $this->parentCheck($datas);
        $datas = match ($datas['type']) {
            1 => $this->getMenuParams($datas),
            2 => $this->getButtonParams($datas),
            default => $this->getCatalogueParams($datas)
        };
        return Permission::create($datas);
    }

    /**
     * 修改权限/菜单/目录
     * @param array $datas 更新的表单数据
     * @return mixed
     */
    public function updatePermission(array $datas): mixed
    {
        $this->parentCheck($datas);
        $permission = Permission::findOrFail($datas['id']);
        $datas = match ($permission['type']) {
            1 => $this->getMenuParams($datas),
            2 => $this->getButtonParams($datas),
            default => $this->getCatalogueParams($datas)
        };
        return $permission->update($datas);

    }

    /**
     * 删除权限
     * @param int $id 权限ID
     * @return mixed
     * @throws BusinessException
     */
    public function deletePermission(int $id): mixed
    {
        $permission = Permission::findOrFail($id);
        if ($permission->children()->first())
            $this->throwBusinessException(info: '请先删除当前权限下的所有子权限');
        return $permission->delete();
    }

    /**
     * 获取权限详情
     * @param int $id 权限ID
     * @return mixed
     */
    public function permissionInfo(int $id): mixed
    {
        return Permission::findOrFail($id);
    }

    /**
     * 根据类型获取所有权限
     * @param array $params
     * @param string $guard_name
     * @return array
     */
    public function getTypePermissions(array $params, string $guard_name = 'sanctum'): array
    {
        $data = Permission::where('guard_name', '=', $guard_name)->orderByDesc('order_num');
        if ($this->isExist($params, 'permission_type')) {
            $data = match ($params['permission_type']) {
                'perm' => $data->where('type', 2),
                'menu' => $data->where('type', '!=', 2),
                default => $data
            };
        }
        return $this->page($params, $data);
    }


    /**
     * 修改目录排序与层级-待完善
     * @param int $dragging 被操作者的ID
     * @param int $drop 操作的ID
     * @param string $type 操作类型 before 至于被操作目录后， after 至于被操作目录前
     * @return bool
     * @throws BusinessException
     */
    public function drop(int $dragging, int $drop, string $type): bool
    {

        switch ($type) {
            case 'before':
                $dropPermission = Permission::findOrFail($drop, ['order_num', 'parent_id']);
                $update = ['order_num' => $dropPermission['order_num'] + 1];
                break;
            case 'after':
                $dropPermission = Permission::findOrFail($drop, ['order_num', 'parent_id']);
                $update = ['order_num' => ($dropPermission['order_num'] - 1) < 1 ? 1 : $dropPermission['order_num'] - 1, 'parent_id' => $drop];
                break;
            default:
                $this->throwBusinessException(info: '参数错误');
        }
        return Permission::where('id', $dragging)->update($update);

    }
}
